using OfficeOpenXml;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.IO;
using System.Collections.Generic;
using System.Globalization;

namespace Tools.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class Ph2LogController : ControllerBase
    {
        private readonly IWebHostEnvironment _environment;
        private readonly ILogger<Ph2LogController> _logger;

        public Ph2LogController(IWebHostEnvironment environment, ILogger<Ph2LogController> logger)
        {
            _environment = environment;
            _logger = logger;
            // 设置EPPlus许可证上下文
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
        }

        [HttpPost("/api/import/ph2-log")]
        public async Task<IActionResult> ImportPh2Log([FromForm] IFormFile file)
        {
            try
            {
                if (file == null || file.Length == 0)
                {
                    return BadRequest(new { success = false, message = "请选择文件" });
                }

                // 验证文件类型（扩展名和内容）
                var validationResult = ValidateFile(file);
                if (!validationResult.Success)
                {
                    return BadRequest(new { success = false, message = validationResult.Message });
                }

                // 读取模板文件（门诊日志模板）
                var templatePath = Path.Combine(_environment.ContentRootPath, "Templates", "门诊日志.xlsx");
                if (!System.IO.File.Exists(templatePath))
                {
                    return StatusCode(500, new { success = false, message = "未找到门诊日志.xlsx模板文件" });
                }

                // 验证模板文件
                var templateValidation = await ValidateExcelFile(templatePath);
                if (!templateValidation.Success)
                {
                    return StatusCode(500, new { success = false, message = $"模板文件验证失败: {templateValidation.Message}" });
                }

                // 创建内存流保存结果
                using (var memoryStream = new MemoryStream())
                {
                    // 复制模板到内存流
                    using (var templateStream = new FileStream(templatePath, FileMode.Open, FileAccess.Read))
                    {
                        await templateStream.CopyToAsync(memoryStream);
                    }

                    // 重置内存流位置
                    memoryStream.Position = 0;

                    // 使用EPPlus处理Excel
                    using (var package = new ExcelPackage(memoryStream))
                    {
                        // 读取上传的文件
                        using (var fileStream = file.OpenReadStream())
                        {
                            // 验证上传文件内容
                            if (!IsValidExcelFile(fileStream))
                            {
                                return BadRequest(new { success = false, message = "上传的文件不是有效的Excel文件或已损坏" });
                            }
                            
                            // 重置流位置
                            fileStream.Position = 0;
                            
                            using (var uploadedPackage = new ExcelPackage(fileStream))
                            {
                                // 处理数据并捕获错误
                                var (success, errorMessage) = ProcessPh2LogData(uploadedPackage, package);
                                if (!success)
                                {
                                    return BadRequest(new { success = false, message = errorMessage });
                                }
                            }
                        }

                        // 保存结果到内存流
                        memoryStream.Position = 0;
                        await package.SaveAsAsync(memoryStream);
                    }

                    // 重置内存流位置用于下载
                    memoryStream.Position = 0;

                    // 移除后端文件名设置，由前端控制下载文件名
                    return File(memoryStream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                }
            }
            catch (InvalidDataException ex)
            {
                _logger.LogError(ex, "Excel文件格式错误");
                return BadRequest(new { success = false, message = $"文件格式错误: 请确保上传的是有效的Excel文件，且未被加密或损坏。详细信息: {ex.Message}" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "PH2门诊日志转换失败");
                return StatusCode(500, new { success = false, message = $"转换过程中发生错误: {ex.Message}" });
            }
        }

        // 文件验证结果
        private (bool Success, string Message) ValidateFile(IFormFile file)
        {
            // 验证文件扩展名
            var fileExtension = Path.GetExtension(file.FileName).ToLower();
            if (fileExtension != ".xlsx" && fileExtension != ".xls")
            {
                return (false, $"不支持的文件类型: {fileExtension}，仅支持.xlsx和.xls格式的文件");
            }

            // 验证文件大小（限制10MB）
            if (file.Length > 10 * 1024 * 1024)
            {
                return (false, "文件过大，请上传不超过10MB的Excel文件");
            }

            return (true, string.Empty);
        }

        // 验证Excel文件是否有效
        private Task<(bool Success, string Message)> ValidateExcelFile(string filePath)
        {
            try
            {
                using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    if (!IsValidExcelFile(stream))
                    {
                        return Task.FromResult((false, "文件不是有效的Excel文件或已损坏"));
                    }
                    
                    stream.Position = 0;
                    using (var package = new ExcelPackage(stream))
                    {
                        // 尝试访问工作表以验证内容
                        if (package.Workbook.Worksheets.Count == 0)
                        {
                            return Task.FromResult((false, "Excel文件中没有工作表"));
                        }
                    }
                }
                return Task.FromResult((true, string.Empty));
            }
            catch (Exception ex)
            {
                return Task.FromResult((false, ex.Message));
            }
        }

        // 检查文件是否为有效的Excel文件（基于文件头）
        private bool IsValidExcelFile(Stream stream)
        {
            // 保存当前位置
            long originalPosition = stream.Position;
            
            try
            {
                // 读取文件头字节
                byte[] headerBytes = new byte[8];
                int bytesRead = stream.Read(headerBytes, 0, headerBytes.Length);
                
                if (bytesRead < 8)
                {
                    return false; // 文件太小，不可能是有效的Excel文件
                }

                // .xlsx文件的魔术数字 (PK ZIP格式)
                bool isXlsx = headerBytes[0] == 0x50 && headerBytes[1] == 0x4B && 
                             (headerBytes[2] == 0x03 && headerBytes[3] == 0x04 || 
                              headerBytes[2] == 0x05 && headerBytes[3] == 0x06 || 
                              headerBytes[2] == 0x07 && headerBytes[3] == 0x08);

                // .xls文件的魔术数字 (BIFF8格式)
                bool isXls = headerBytes[0] == 0xD0 && headerBytes[1] == 0xCF && 
                            headerBytes[2] == 0x11 && headerBytes[3] == 0xE0 && 
                            headerBytes[4] == 0xA1 && headerBytes[5] == 0xB1 && 
                            headerBytes[6] == 0x1A && headerBytes[7] == 0xE1;

                return isXlsx || isXls;
            }
            finally
            {
                // 恢复流位置
                stream.Position = originalPosition;
            }
        }

        private (bool Success, string Message) ProcessPh2LogData(ExcelPackage uploadedPackage, ExcelPackage templatePackage)
        {
            try
            {
                // 获取上传文件的第一个工作表
                var uploadedSheet = uploadedPackage.Workbook.Worksheets[0];
                if (uploadedSheet.Dimension == null)
                {
                    return (false, "上传文件没有数据");
                }

                // 获取模板文件的第一个工作表
                var templateSheet = templatePackage.Workbook.Worksheets[0];
                if (templateSheet.Dimension == null)
                {
                    return (false, "模板文件没有数据");
                }

                // 清空模板文件中除表头外的所有数据行
                if (templateSheet.Dimension.Rows > 1)
                {
                    templateSheet.DeleteRow(2, templateSheet.Dimension.Rows - 1);
                }

                // 获取上传文件的表头行（假设第一行为表头）
                var uploadedHeaders = new Dictionary<string, int>();
                int headerRow = 1;
                for (int col = 1; col <= uploadedSheet.Dimension.End.Column; col++)
                {
                    string header = uploadedSheet.Cells[headerRow, col].Text.Trim();
                    if (!string.IsNullOrEmpty(header))
                    {
                        uploadedHeaders[header] = col;
                    }
                }

                // 获取模板文件的表头行（假设第一行为表头）
                var templateHeaders = new Dictionary<string, int>();
                for (int col = 1; col <= templateSheet.Dimension.End.Column; col++)
                {
                    string header = templateSheet.Cells[headerRow, col].Text.Trim();
                    if (!string.IsNullOrEmpty(header))
                    {
                        templateHeaders[header] = col;
                    }
                }

                // 处理数据行
                int startRow = 2; // 从第二行开始处理数据
                int maxRows = Math.Min(uploadedSheet.Dimension.End.Row, 10000); // 限制最多处理10000行数据

                for (int row = startRow; row <= maxRows; row++)
                {
                    // 插入新行
                    if (row > startRow)
                    {
                        templateSheet.InsertRow(2, 1);
                    }

                    // 遍历模板文件的所有字段，根据名称匹配
                    foreach (var templateHeader in templateHeaders)
                    {
                        string targetField = templateHeader.Key;
                        int targetCol = templateHeader.Value;
                        string sourceField = targetField;

                        // 应用特殊字段映射规则 - 规则4：证件号：身份证号（左边为导入的字段，右边为目标匹配表格的字段）
                        // 注意：根据需求描述，这可能意味着导入文件中的"证件号"字段应映射到模板中的"身份证号"字段
                        // 但这里需要确认具体映射关系，暂时假设是这种映射
                        if (targetField == "身份证号")
                        {
                            sourceField = "证件号";
                        }

                        // 检查源字段是否存在
                        if (uploadedHeaders.ContainsKey(sourceField))
                        {
                            int sourceCol = uploadedHeaders[sourceField];
                            
                            // 获取源数据
                            var cell = uploadedSheet.Cells[row, sourceCol];
                            object sourceValue = cell.Value;
                            string sourceText = cell.Text.Trim();

                            // 设置目标单元格的值
                            var targetCell = templateSheet.Cells[2, targetCol];
                            
                            // 规则3：在生成新表格的时候，将为纯数字且长度超过6的值设置为纯文本
                            if (IsLongNumber(sourceText) || targetField == "身份证号" || targetField == "证件号")
                            {
                                targetCell.Style.Numberformat.Format = "@";
                                targetCell.Value = sourceText;
                            }
                            // 对其他数值类型字段尝试转换为数字
                            else if (int.TryParse(sourceText, out int intValue))
                            {
                                targetCell.Value = intValue;
                            }
                            else if (decimal.TryParse(sourceText, out decimal decimalValue))
                            {
                                targetCell.Value = decimalValue;
                            }
                            else if (targetField == "手机号" || targetField == "联系电话")
                            {
                                // 手机号或联系电话为"-"或包含非数字字符时转换为空
                                if (string.IsNullOrWhiteSpace(sourceText) || sourceText == "-" || sourceText.Trim() == "-" || !System.Text.RegularExpressions.Regex.IsMatch(sourceText, @"^\d+$"))
                                {
                                    targetCell.Value = string.Empty;
                                }
                                else
                                {
                                    targetCell.Value = sourceText;
                                }
                            }
                            else
                            {
                                targetCell.Value = sourceText;
                            }
                        }
                        // 规则2：目标匹配表的字段顺序不能更改，内容可以为空
                        // 不需要特殊处理，保持原字段顺序即可
                    }
                }

                return (true, string.Empty);
            }
            catch (Exception ex)
            {
                return (false, $"处理数据时发生错误: {ex.Message}");
            }
        }

        // 判断是否为需要设置为文本格式的长数字 - 规则3
        private bool IsLongNumber(string value)
        {
            if (string.IsNullOrEmpty(value)) return false;
            return value.All(char.IsDigit) && value.Length > 6;
        }
    }
}